#include <stdio.h>
#include "app/ApplicationConfig.h"
#include "parser/Rule.h"
#include "parser/Parser.h"
#include "parser/ParsedData.h"
#include "util/exceptions/Exception.h"
#include "util/StringUtils.h"

namespace app {

util::Dictionary<std::string, std::string> ApplicationConfig::propertyList;

ApplicationConfig::ApplicationConfig() {

}
ApplicationConfig::~ApplicationConfig() {
	util::LinkedList<string>::Iterator keys = propertyList.keySet().iterator();
	while(keys.hasNext()) {
		delete propertyList.remove(*keys.next());
	}

}
bool ApplicationConfig::loadConfigFromFile(std::string fileName) {
	parser::ConfigEntryRule rule(':');
	parser::Parser pars(&rule, fileName);
	while (!pars.noMoreDataInFile()) {
		parser::ConfigEntryParsedData* data = NULL;
		try {
			data = (parser::ConfigEntryParsedData*) (pars.processNextLine());
			propertyList.put(data->getKey(), new std::string(data->getValue()));
			delete data;
		} catch (parser::InvalidDataException &e) {
			printf("Error cargando configuracion en %s linea %s: %s\n",
					fileName.c_str(), pars.getStrLineNumber().c_str(),
					e.getMessage().c_str());
		} catch (util::Exception &e) {
			printf("Error cargando configuracion: %s\n", e.getMessage().c_str());
			return false;
		}
	}
	return true;
}

std::string ApplicationConfig::getProperty(std::string id)
		throw (util::ElementNotFoundException) {
	return *propertyList.get(id);
}

int ApplicationConfig::getIntProperty(std::string id)
		throw (util::ElementNotFoundException, parser::InvalidDataException) {
	return util::stringToInt(getProperty(id));
}

bool ApplicationConfig::getBooleanProperty(std::string id) {
	try {
		return (getProperty(id).compare("true") == 0);
	} catch (util::ElementNotFoundException &e) {
		return false;
	}
}

std::string ApplicationConfig::getOptionalProperty(std::string id, std::string defaultValue) {
	try {
		return getProperty(id);
	} catch (util::ElementNotFoundException &e) {
		return defaultValue;
	}
}

int ApplicationConfig::getOptionalIntProperty(std::string id, int defaultValue) {
	try {
		return util::stringToInt(getProperty(id));
	} catch (util::Exception &e) {
		return defaultValue;
	}
}

}
